package com.sxjg.service;

import com.sxjg.pojo.ResponseBean;
import com.sxjg.pojo.VacationApproveVo;
import com.sxjg.pojo.VacationInfo;
import com.sxjg.pojo.VacationRequestVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

/**
 * @project 请假流程测试
 * @Description
 * @Author songwp
 * @Date 2023/2/13 20:08
 * @Version 1.0.0
 **/
@Service
@Slf4j
public class VacationService {

    // 本地磁盘D：//
    @Value("${bpmn.path:{null}}")
    private String bpmnPath;
    //在yml文件中配置好的端口好
    @Value("${server.port:{null}}")
    private String port;

    @Autowired
    RuntimeService runtimeService;
    @Autowired
    TaskService taskService;
    @Autowired
    HistoryService historyService;
    @Autowired
    RepositoryService repositoryService;
    @Resource
    private ProcessEngine processEngine;

    /**
     * 申请请假
     * @param vacationRequestVO
     * @return
     */
    @Transactional
    public ResponseBean askForLeave(VacationRequestVo vacationRequestVO) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("name", vacationRequestVO.getName());
        variables.put("days", vacationRequestVO.getDays());
        variables.put("reason", vacationRequestVO.getReason());
        try {
            //指定业务流程
            ProcessInstance vacationRequest = runtimeService.startProcessInstanceByKey("vacationRequest", vacationRequestVO.getName(), variables);
            return ResponseBean.ok("已提交请假申请",vacationRequest.getProcessInstanceId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseBean.error("提交申请失败");
    }

    /**
     * 审批列表
     * @param identity
     * @return
     */
    public ResponseBean leaveList(String identity) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(identity).list();
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < tasks.size(); i++) {
            Task task = tasks.get(i);
            Map<String, Object> variables = taskService.getVariables(task.getId());
            variables.put("id", task.getId());
            list.add(variables);
        }
        return ResponseBean.ok("加载成功", list);
    }


    /**
     * 查看当前流程图已到达节点(包含路径)
     * @param processId
     * @return
     */
    public ResponseBean getProcessPicture(String processId){
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
        String photoUrlByFileName = null;
        try {
            //流程图名称
            String pngName = null;
            if(processInstance.getProcessDefinitionName().contains("/")){
                pngName = processInstance.getProcessDefinitionName().substring(processInstance.getProcessDefinitionName().indexOf("/")+1,processInstance.getProcessDefinitionName().length());
            }else{
                pngName = processInstance.getProcessDefinitionName().substring(processInstance.getProcessDefinitionName().indexOf("\\")+1,processInstance.getProcessDefinitionName().length());
            }
            //pngPath 本地存储流程图的路径  bpmnPath是在yml中配置的路径 D：//  pngName是上面切割出来的流程图名称
            String pngPath = bpmnPath+pngName;
            //判断是否已存在
            File file = new File(pngPath);
            if(file.exists()){
                //存在
                //getPhotoUrlByFileName 方法是我自己封装的获取图片url地址的方法
                photoUrlByFileName = getPhotoUrlByFileName(pngName);
            }else{
                //不存在
                InputStream resourceAsStream = processEngine.getRepositoryService().getResourceAsStream(processInstance.getDeploymentId(), processInstance.getProcessDefinitionName());
                //写入本地
                FileUtils.copyInputStreamToFile(resourceAsStream, new File(pngPath));
                //getPhotoUrlByFileName 方法是我自己封装的获取图片url地址的方法
                photoUrlByFileName = getPhotoUrlByFileName(pngName);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseBean.ok("加载成功", photoUrlByFileName);
    }

    /**
     * 操作审批
     * @param vacationVO
     * @return
     */
    public ResponseBean askForLeaveHandler(VacationApproveVo vacationVO) {
        try {
            boolean approved = vacationVO.getApprove();
            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("approved", approved);
            variables.put("employee", vacationVO.getName());
            Task task = taskService.createTaskQuery().taskId(vacationVO.getTaskId()).singleResult();
            taskService.complete(task.getId(), variables);
            // 0 未提交  1 审批通过  2 已驳回
            int approvedStatus = 0;
            if (approved) {
                //如果是同意，还需要继续走一步
                Task t = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
                taskService.complete(t.getId());
                approvedStatus = 1;
            }else {
                approvedStatus = 2;
            }
            return ResponseBean.ok("操作成功",approvedStatus);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseBean.error("操作失败");
    }

    /**
     * 请假列表
     * @param name
     * @return
     */
    public ResponseBean searchResult(String name) {
        List<VacationInfo> vacationInfos = new ArrayList<>();
        List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(name).finished().orderByProcessInstanceEndTime().desc().list();
        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
            VacationInfo vacationInfo = new VacationInfo();
            Date startTime = historicProcessInstance.getStartTime();
            Date endTime = historicProcessInstance.getEndTime();
            List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery()
                    .processInstanceId(historicProcessInstance.getId())
                    .list();
            for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
                String variableName = historicVariableInstance.getVariableName();
                Object value = historicVariableInstance.getValue();
                if ("reason".equals(variableName)) {
                    vacationInfo.setReason((String) value);
                } else if ("days".equals(variableName)) {
                    vacationInfo.setDays(Integer.parseInt(value.toString()));
                } else if ("approved".equals(variableName)) {
                    vacationInfo.setStatus((Boolean) value);
                } else if ("name".equals(variableName)) {
                    vacationInfo.setName((String) value);
                }
            }
            vacationInfo.setStartTime(startTime);
            vacationInfo.setEndTime(endTime);
            vacationInfos.add(vacationInfo);
        }
        return ResponseBean.ok("ok", vacationInfos);
    }

    /**
     * @Author: songwp
     * @Description: 获取图片url地址
     * @DateTime: 16:30 2022/7/21
     * @Params: 图片名称
     * @Return 图片url地址
     */
    public String getPhotoUrlByFileName(String name){
        String hostAddress = null;
        //获取本地IP地址
        try {
            hostAddress = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            return null;
        }
        String photoUrl = null;
        if(name.contains(".png")){
            photoUrl = "http://"+hostAddress+":"+port+"/api/image/"+name;
        }else{
            photoUrl = "http://"+hostAddress+":"+port+"/api/image/"+name+".png";
        }

        return photoUrl;
    }

}
